package is.glif.fenius.translators.nrc.invoke;

import static java.util.Arrays.asList;
import is.glif.fenius.api.TranslatorFactory;
import is.glif.fenius.translators.nrc.NRCTranslator;
import is.glif.fenius.util.ConfigManager;
import is.glif.fenius.util.JettyContainer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import joptsimple.OptionParser;
import joptsimple.OptionSet;

public class Invoker {

    private static Map config;
    private static HashMap<String, Object> servicesToExpose;
    private static Integer port = 8080;
    private static String hostname = "localhost";

    public static void main(String[] args) throws Exception {

    	System.out.println("A");
        configure();
        System.out.println("B");
        // create a parser
        OptionParser parser = new OptionParser() {
            {
                acceptsAll( asList( "h", "?" ), "show help then exit" );
                accepts( "help", "show extended help then exit" );
                accepts( "port" , "HTTP port" ).withRequiredArg().describedAs("int (default: "+port+")").ofType(Integer.class);
                accepts( "host" , "HTTP hostname" ).withRequiredArg().describedAs("string (default: "+hostname+")").ofType(String.class);
            }
        };

        System.out.println("C");
        OptionSet options = parser.parse( args );

        System.out.println("D");
        // check for help
        if ( options.has( "?" ) || options.has("h") || options.has("help")) {
            parser.printHelpOn( System.out );
            System.exit(0);
        }

        NRCTranslator t = new NRCTranslator();
        System.out.println("E");
        TranslatorFactory f = TranslatorFactory.getInstance();
        System.out.println("F");
        f.setTranslator(t);

        if (options.has("port")) {
            port = (Integer) options.valueOf("port");
        }
        if (options.has("host")) {
            hostname = (String) options.valueOf("host");
        }

        System.out.println("G");
        JettyContainer jc = new JettyContainer();
        System.out.println("H");
        jc.setPort(port);
        jc.setHostname(hostname);

        jc.setServicesToExpose(servicesToExpose);
        jc.startServer();
        System.out.println("I");

        while (true) {
            Thread.sleep(100);
        }

    }

    @SuppressWarnings("unchecked")
    private static void configure() {
        ConfigManager cm = ConfigManager.getInstance();
        config = cm.getConfiguration();
        Map httpConfig = (Map) config.get("http");
        port = (Integer) httpConfig.get("port");
        hostname = (String) httpConfig.get("hostname");

        servicesToExpose = new HashMap<String, Object>();

        ArrayList<Map> servicesConfig = (ArrayList<Map>) config.get("services");
        for (Map serviceConfig : servicesConfig) {
            String path = (String) serviceConfig.get("path");
            String impl = (String) serviceConfig.get("implementor");
            Class c = null;
            try {
                c = Class.forName(impl);
                Object implementorObj = c.getConstructor((Class[]) null).newInstance((Object[]) null);
                servicesToExpose.put(path, implementorObj);
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("Problem loading class: "+impl);
                System.exit(1);
            }
        }
    }

}
